# python学习 至此开始
# 学习日期: 2023/8/15 10:08
# 学习者: 任磊
# 坦克大战1.20 版本


"""
此版本会对初始版本进行部分功能的添加，会添加部分额外功能，具体细节请详见以下说明部分：
1，增加游戏胜利结算，失败结算以及结束游戏  (完成添加，游戏胜利结算以及失败次数统计，失败条件判断以及结束游戏)
2，优化爆炸效果  (完成优化，添加爆炸效果图像颜色细节)
3，增加更多障碍物，以及障碍物对应的属性  (完成添加，两种墙体以及对应的生命值,河流类以及对应的暂时无法破坏属性)
4，增加敌方坦克类型，以及对应敌方坦克的属性  (完成添加，添加了敌方坦克类型以及对应的属性，虎式生命值高攻速慢移速低，鼠式生命值低攻速快移速高)
5,优化敌方坦克算法，包括 射击，移动  (完成封装，为敌方坦克封装攻速，移速属性)
6,添加我方核心物体，用以判断失败条件  (完成添加，初始生命值耗尽后，游戏自动结束)
@author:renLei
此版本完成日期；2023.8.16.19:14
"""

import pygame
import random
import time


# 主游戏类
class MainGame(object):
    # 游戏主窗口
    version = 'v1.10'
    window = None
    SCREEN_HEIGHT = 1000
    SCREEN_WIDTH = 1700
    BACKGROUND_COLOR = pygame.Color(0, 0, 0)
    COLOR_RED = pygame.Color(255, 0, 0)
    # 窗口内允许最大物体移动速度
    Max_speed = 15
    # 创建我方坦克
    TANK_P1 = None
    # 创建敌方坦克
    EnemyTank_list = []
    # 敌方坦克数量
    EnemyTank_count = 6
    # 存储我方子弹的列表
    Bullet_list = []
    # 我方最大子弹数量限制
    Max_bullet_count = 3
    # 存储敌方子弹的列表
    eBullet_list = []
    # 敌方最大子弹数量限制
    Max_eBullet_count = 15
    # 爆炸效果列表
    Explode_list = []
    # 障碍物列表
    Barrier_list = []
    # 最大障碍物数量
    Max_barrier_count = 20
    # 核心建筑
    heart = None
    # 游戏结束条件
    gameOver = False

    def __init__(self):
        pass

    # 开始游戏
    def startGame(self):
        # 初始化显示模块
        pygame.display.init()
        # 创建窗口，加载窗口(借鉴官方文档)
        MainGame.window = pygame.display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])
        # 创建我方坦克
        self.creatMyTank()
        # 创建敌方所有类型坦克
        self.creatEnemyTank_tiger()
        self.creatEnemyTank_mouse()
        # 创建所有障碍物类型
        self.creatWall_stone()
        self.creatWall_wood()
        self.creatRiver()
        # 创建我方核心建筑
        self.creatHeart()
        # 设置游戏标题
        pygame.display.set_caption("坦克大战{}".format(MainGame.version))
        # 让窗口持续刷新
        while True:
            # 给窗口完成一个颜色填充
            MainGame.window.fill(MainGame.BACKGROUND_COLOR)
            # 在循环中持续完成事件的获取
            self.getEvent()
            # 将绘制的文字粘贴到窗口中
            MainGame.window.blit(self.getTextSurface("剩余敌方坦克{}辆,核心建筑剩余生命值{},".format(len(MainGame.EnemyTank_list), MainGame.heart.hp), self.EnemyTank_list), (5, 5))
            # 调用障碍物展示方法
            self.blitBarriers()
            if MainGame.TANK_P1 and MainGame.TANK_P1.live:
                # 将我方坦克加入到窗口中
                MainGame.TANK_P1.displayTank()
            else:
                del MainGame.TANK_P1
                MainGame.TANK_P1 = None
            # 循环展示敌方坦克
            self.blitEnemyTank()
            # 循环展示我方核心建筑
            self.blitHeart()
            # 控制坦克移动条件
            if MainGame.TANK_P1 and not MainGame.TANK_P1.stop:
                MainGame.TANK_P1.move()
                # 坦克碰撞墙壁检测
                MainGame.TANK_P1.hitBarrier()
                # 坦克碰撞敌方坦克检测
                MainGame.TANK_P1.hitEnemyTank()
            # 调用子弹渲染列表的方法
            self.blitBullet()
            self.blitEnemyBullet()
            # 调用爆炸效果展示方法
            self.blitExplodes()
            # 窗口的刷新
            pygame.display.update()
            time.sleep(0.02)
            if MainGame.gameOver:
                music = Music(r"E:\summer_term_2023\pythonProject\tankGame\tank_music\gameEnd.mp3")
                music.play()
                time.sleep(59)
                MainGame.endGame(self)

    # 创建我方坦克
    def creatMyTank(self):
        MainGame.TANK_P1 = MyTank(MainGame.SCREEN_WIDTH/2, MainGame.SCREEN_HEIGHT - 300)
        # 创建音乐对象
        music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\gameStart.mp3')
        # 播放音效
        music.play()

    # 创建敌方坦克类型1
    def creatEnemyTank_tiger(self):
        top = 100
        for i in range(MainGame.EnemyTank_count):
            speed = random.randint(EnemyTank_tiger.leastSpeed, EnemyTank_tiger.maxSpeed)
            # 每次都随机生成一个left值
            left = random.randint(1, 5)
            eTank = EnemyTank_tiger(left * 100, top, speed)
            MainGame.EnemyTank_list.append(eTank)

    # 创建敌方坦克类型2
    def creatEnemyTank_mouse(self):
        top = 50
        for i in range(MainGame.EnemyTank_count):
            speed = random.randint(EnemyTank_mouse.leastSpeed, EnemyTank_mouse.maxSpeed)
            # 随机生成left值
            left = random.randint(1, 5)
            etank = EnemyTank_mouse(left * 100, top, speed)
            MainGame.EnemyTank_list.append(etank)

    # 将敌方坦克加入到窗口中
    def blitEnemyTank(self):
        for eTank in MainGame.EnemyTank_list:
            # 判断坦克存活状态
            if eTank.live:
                eTank.displayEnemyTank()
                # 敌方坦克的移动方法
                eTank.randomMove()
                # 敌方坦克碰撞墙壁检测
                eTank.hitBarrier()
                if MainGame.heart.live:
                    # 敌方坦克碰撞我方核心建筑检测
                    eTank.hitHeart()
                    if MainGame.TANK_P1:
                        # 我方坦克碰撞到核心建筑检测
                        MainGame.TANK_P1.hitHeart()
                if MainGame.TANK_P1:
                    # 敌方坦克碰撞到我方坦克方法
                    eTank.hitMyTank()
                # 调用敌方坦克的射击方法
                # if random.randint(1, 20) == 10:  # 此方法也可使敌方坦克随机发射炮弹
                eBullet = eTank.shot()
                # 判断子弹是否为空
                if eBullet is not None:
                    # 将敌方子弹存储到子弹列表中
                    MainGame.eBullet_list.append(eBullet)
            else:
                # 移除坦克
                MainGame.EnemyTank_list.remove(eTank)

    # 创建墙壁类型 1方法
    def creatWall_stone(self):
        for i in range(1, MainGame.Max_barrier_count):
            wall = Wall_stone(55 * i, 400)
            MainGame.Barrier_list.append(wall)

    # 创建墙壁类型 2方法
    def creatWall_wood(self):
        for i in range(1, MainGame.Max_barrier_count):
            wall = Wall_wood(100*i, 300)
            MainGame.Barrier_list.append(wall)

    # 创建河流类障碍物
    def creatRiver(self):
        for i in range(1, MainGame.Max_barrier_count):
            river = River(MainGame.SCREEN_WIDTH - 54 * i, 600)
            MainGame.Barrier_list.append(river)

    # 创建我方核心物体
    def creatHeart(self):
        MainGame.heart = Heart(MainGame.SCREEN_WIDTH / 2, MainGame.SCREEN_HEIGHT - 70)

    # 将墙壁加入到窗口中
    def blitBarriers(self):
        for barrier in MainGame.Barrier_list:
            if barrier.live:
                barrier.displayBarrier()
            else:
                MainGame.Barrier_list.remove(barrier)

    # 将我方子弹加入到窗口中
    def blitBullet(self):
        for bullet in MainGame.Bullet_list:
            # 判断子弹是否应该存在
            if bullet.live:
                bullet.displayBullet()
                # 让子弹移动e
                bullet.bulletMove()
                # 调用我方子弹与敌方坦克碰撞方法
                bullet.hitEnemyTank()
                # 调用我方子弹是否与墙壁碰撞方法
                bullet.hitBarrier()
                # 调用子弹与我方核心建筑碰撞方法
                bullet.hitHeart()
            else:
                # 子弹无效，从子弹列表中去除
                MainGame.Bullet_list.remove(bullet)

    # 将敌方子弹加入到窗口中
    def blitEnemyBullet(self):
        for eBullet in MainGame.eBullet_list:
            if eBullet.live:
                eBullet.displayBullet()
                eBullet.bulletMove()
                # 调用敌方子弹是否与墙壁碰撞方法
                eBullet.hitBarrier()
                if MainGame.heart.live:
                    eBullet.hitHeart()
                if MainGame.TANK_P1 and MainGame.TANK_P1.live:
                    eBullet.hitMyTank()
            else:
                MainGame.eBullet_list.remove(eBullet)

    # 爆炸效果展示
    def blitExplodes(self):
        for explode in MainGame.Explode_list:
            if explode.live:
                explode.displayExplode()
            else:
                MainGame.Explode_list.remove(explode)

    # 展示我方核心建筑
    def blitHeart(self):
        # 判断核心建筑是否存在
        if MainGame.heart.live:
            MainGame.heart.display()
        else:
            pass

    # 获取运行期间所有的事件(包括鼠标事件，键盘事件)
    def getEvent(self):
        # 1 获取事件
        eventList = pygame.event.get()
        # 2 判断事件并进行处理（点击关闭，键盘）
        for item in eventList:
            # 判断是否点击退出
            if item.type == pygame.QUIT:
                self.endGame()
            # 判断事件类型是否为按键，若是，继续判断为哪个按键，并进行相应处理
            if item.type == pygame.KEYDOWN:
                if item.key == pygame.K_ESCAPE and not MainGame.TANK_P1:
                    # 调用创建我方坦克
                    MainGame.creatMyTank(self)
                # 具体按键的值的处理
                if MainGame.TANK_P1:
                    if item.key == pygame.K_LEFT:
                        MainGame.TANK_P1.direction = 'L'
                        # MainGame.TANK_P1.move()
                        MainGame.TANK_P1.stop = False
                        print("坦克向左掉头，接着移动")
                    elif item.key == pygame.K_RIGHT:
                        MainGame.TANK_P1.direction = 'R'
                        # MainGame.TANK_P1.move()
                        MainGame.TANK_P1.stop = False
                        print("坦克向右调头，接着移动")
                    elif item.key == pygame.K_UP:
                        MainGame.TANK_P1.direction = 'U'
                        # MainGame.TANK_P1.move()
                        MainGame.TANK_P1.stop = False
                        print("坦克向上调头，接着移动")
                    elif item.key == pygame.K_DOWN:
                        MainGame.TANK_P1.direction = 'D'
                        # MainGame.TANK_P1.move()
                        MainGame.TANK_P1.stop = False
                        print("坦克向下调头，接着移动")
                    elif item.key == pygame.K_SPACE:
                        print("坦克发射炮弹")
                        if len(MainGame.Bullet_list) < MainGame.Max_bullet_count:
                            # 产生一颗子弹
                            m = Bullet(MainGame.TANK_P1)
                            # 讲子弹加入到子弹列表
                            MainGame.Bullet_list.append(m)
                            # 创建发射音效
                            music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\tankShot_normal.mp3')
                            music.play()
                        else:
                            print("子弹数量超过限制")
                        print("当前屏幕中的子弹数量为：{}".format(len(MainGame.Bullet_list)))
                else:
                    print("无效操作")
            if MainGame.TANK_P1:
                if item.type == pygame.KEYUP:
                    # 判断按键，修改移动开关
                    if item.key == pygame.K_LEFT or item.key == pygame.K_RIGHT or item.key == pygame.K_UP or item.key == pygame.K_DOWN:
                        MainGame.TANK_P1.stop = True

    def getTextSurface(self, text, flag):
        # fontList = pygame.font.get_fonts()  获取系统所支持的所有字体
        # 初始化字体模块
        pygame.font.init()
        # 选中合适的字体
        font = pygame.font.SysFont('kaiti', 18)
        # 使用相应的字符完成相关的内容绘制
        # 判断核心建筑是否存在
        if MainGame.heart.live:
            if not flag:
                # 调用胜利结算
                endtext = text + MainGame.victory(self) + str(MyTank.recover_time)
                textSurface = font.render(endtext, True, [255, 0, 0])
                return textSurface
            else:
                endtext = text
                textSurface = font.render(endtext, True, [255, 0, 0])
                return textSurface
        else:
            # 调用失败结算
            endtext = text + MainGame.fail(self)
            textSurface = font.render(endtext, True, [255, 0, 0])
            return textSurface

    # 游戏胜利结算
    def victory(self):
        # 胜利结算语
        MainGame.gameOver = True
        text = "恭喜胜利,被击毁次数:"
        return text

    # 游戏失败结算
    def fail(self):
        MainGame.gameOver = True
        text = "很遗憾，失败"
        return text

    # 结束游戏
    def endGame(self):
        print('欢迎使用')
        exit()


# 基础类（用于pygame中的碰撞检测）
class BaseItem(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)


# 基础坦克类
class Tank(BaseItem):
    direction = 'U'

    def __init__(self, left, top):
        super().__init__()
        self.images = {
            'U': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank1_N.png'),
            'D': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank1_S.png'),
            'R': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank1_E.png'),
            'L': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank1_W.png')
        }
        self.image = self.images[self.direction]
        # 坦克所在的区域
        self.rect = self.image.get_rect()
        # 指定坦克初始化位置
        self.rect.left = left
        self.rect.top = top
        # 新增移动速度属性
        self.speed = 5
        # 坦克移动开关
        self.stop = True
        # 增加坦克状态属性
        self.live = True
        # 坦克位置记录(用于还原时使用)
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top
        # 坦克基础生命值 默认为 1
        self.hp = 1

    # 坦克的移动方法
    def move(self):
        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top
        if self.direction == 'L':
            if self.rect.left > 0:
                self.rect.left -= self.speed
        elif self.direction == 'R':
            if self.rect.left + self.rect.width < MainGame.SCREEN_WIDTH:
                self.rect.left += self.speed
        elif self.direction == 'U':
            if self.rect.top > 30:
                self.rect.top -= self.speed
        elif self.direction == 'D':
            if self.rect.top + self.rect.height < MainGame.SCREEN_HEIGHT - 10:
                self.rect.top += self.speed

    # 保持坦克不动的方法
    def stay(self):
        self.rect.left = self.oldLeft
        self.rect.top = self.oldTop

    # 坦克接触障碍物类方法
    def hitBarrier(self):
        for barrier in MainGame.Barrier_list:
            if pygame.sprite.collide_rect(barrier, self):
                self.stay()

    # 坦克的射击方法
    def shot(self):
        return Bullet(self)

    # 展示坦克（将坦克这个surface绘制到窗口中）
    def displayTank(self):
        # 1 重新设置坦克图片
        self.image = self.images[self.direction]
        # 2 将坦克加入到窗口中
        MainGame.window.blit(self.image, self.rect)


# 我方坦克类
class MyTank(Tank):
    # 记录我方坦克失败次数
    recover_time = 0

    def __init__(self, left, top):
        super(MyTank, self).__init__(left, top)
        # 设置我方坦克初始生命值
        self.hp = 1

    # 主动碰撞到敌方坦克方法
    def hitEnemyTank(self):
        for eTank in MainGame.EnemyTank_list:
            if pygame.sprite.collide_rect(self, eTank):
                self.stay()

    # 主动碰撞到核心建筑方法
    def hitHeart(self):
        if MainGame.heart.live:
            if pygame.sprite.collide_rect(self, MainGame.heart):
                self.stay()
            else:
                pass


# 敌方虎式坦克类
class EnemyTank_tiger(Tank):
    # 该类坦克初始移速属性
    leastSpeed = 3
    maxSpeed = 5

    def __init__(self, left, top, speed):
        super(EnemyTank_tiger, self).__init__(left, top)
        self.images = {
            'U': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank2_N.png'),
            'D': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank2_S.png'),
            'R': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank2_E.png'),
            'L': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank2_W.png')
        }
        self.randDirection()
        self.image = self.images[self.direction]
        # 坦克所在的区域
        self.rect = self.image.get_rect()
        # 指定坦克初始化位置
        self.rect.left = left
        self.rect.top = top
        # 新增移动速度属性
        self.speed = speed
        # 坦克移动开关
        self.stop = True
        # 新增步数属性 ，用以控制敌方坦克随机移动
        self.step = 50
        # 该类型坦克的生命值
        self.hp = 10
        # 该类坦克攻速初始属性
        self.attack_speed = 21

    def randDirection(self):
        num = random.randint(1, 4)
        if num == 1:
            self.direction = 'U'
        elif num == 2:
            self.direction = 'D'
        elif num == 3:
            self.direction = 'R'
        elif num == 4:
            self.direction = 'L'

    def displayEnemyTank(self):
        super().displayTank()

    # 随机移动
    def randomMove(self):
        if self.step <= 0:
            self.randDirection()
            self.step = random.randint(40, 60)
        else:
            self.move()
            self.step -= 1

    # 敌方坦克随机射击方法
    def shot(self):
        num = random.randint(1, 1000)
        if num <= self.attack_speed:
            return Bullet(self)

    # 敌方坦克碰撞到我方坦克方法
    def hitMyTank(self):
        if pygame.sprite.collide_rect(MainGame.TANK_P1, self):
            self.stay()

    # 敌方坦克碰撞我方核心建筑方法
    def hitHeart(self):
       if pygame.sprite.collide_rect(MainGame.heart, self):
           self.stay()


# 敌方鼠式坦克类
class EnemyTank_mouse(Tank):
    # 该类坦克初始移速属性
    leastSpeed = 4
    maxSpeed = 8

    def __init__(self, left, top, speed):
        super(Tank, self).__init__()
        self.images = {
            'U': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank3_N.png'),
            'D': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank3_S.png'),
            'R': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank3_E.png'),
            'L': pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\Tank3_W.png')
        }
        self.randDirection()
        self.image = self.images[self.direction]
        # 坦克所在的区域
        self.rect = self.image.get_rect()
        # 指定坦克初始化位置
        self.rect.left = left
        self.rect.top = top
        # 新增移动速度属性
        self.speed = speed
        # 坦克移动开关
        self.stop = True
        # 新增步数属性 ，用以控制敌方坦克随机移动
        self.step = 50
        # 该类型坦克的生命值
        self.hp = 2
        # 该类型坦克的状态
        self.live = True
        # 该类坦克初始攻速属性
        self.attack_speed = 41

    def randDirection(self):
        num = random.randint(1, 4)
        if num == 1:
            self.direction = 'U'
        elif num == 2:
            self.direction = 'D'
        elif num == 3:
            self.direction = 'R'
        elif num == 4:
            self.direction = 'L'

    def displayEnemyTank(self):
        super().displayTank()

    # 随机移动
    def randomMove(self):
        if self.step <= 0:
            self.randDirection()
            self.step = random.randint(70, 100)
        else:
            self.move()
            self.step -= 1

    # 敌方坦克随机射击方法
    def shot(self):
        num = random.randint(1, 1000)
        if num <= self.attack_speed:
            return Bullet(self)

    # 敌方坦克碰撞到我方坦克方法
    def hitMyTank(self):
        if pygame.sprite.collide_rect(MainGame.TANK_P1, self):
            self.stay()

    # 敌方坦克碰撞我方核心建筑方法
    def hitHeart(self):
        if pygame.sprite.collide_rect(MainGame.heart, self):
            self.stay()


# 子弹类
class Bullet(BaseItem):
    def __init__(self, tank):
        # 图片
        super().__init__()
        self.image = pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\bullet3.png')
        # 方向（坦克方向）
        self.direction = tank.direction
        # 位置
        self.rect = self.image.get_rect()
        if self.direction == 'U':
            self.rect.left = tank.rect.left + tank.rect.width/2 - self.rect.width/2
            self.rect.top = tank.rect.top - self.rect.height
        elif self.direction == 'D':
            self.rect.left = tank.rect.left + tank.rect.width / 2 - self.rect.width / 2
            self.rect.top = tank.rect.top + tank.rect.height
        elif self.direction == 'L':
            self.rect.left = tank.rect.left
            self.rect.top = tank.rect.top + tank.rect.width/2 - self.rect.width/2
        elif self.direction == 'R':
            self.rect.left = tank.rect.left + tank.rect.width
            self.rect.top = tank.rect.top + tank.rect.width/2 - self.rect.width/2
        # 子弹移动速度(默认为窗口内最大移动速度)
        self.speed = MainGame.Max_speed
        # 为子弹添加状态值(用以是否使子弹消失)
        self.live = True

    # 子弹移动的方法
    def bulletMove(self):
        if self.direction == 'U':
            if self.rect.top > 0:
                self.rect.top -= self.speed
            else:
                self.live = False
        elif self.direction == 'D':
            if self.rect.top + self.rect.height < MainGame.SCREEN_HEIGHT:
                self.rect.top += self.speed
            else:
                self.live = False
        elif self.direction == 'R':
            if self.rect.left + self.rect.width < MainGame.SCREEN_WIDTH:
                self.rect.left += self.speed
            else:
                self.live = False
        elif self.direction == 'L':
            if self.rect.left > 0:
                self.rect.left -= self.speed
            else:
                self.live = False

    # 子弹展示的类
    def displayBullet(self):
        MainGame.window.blit(self.image, self.rect)

    # 我方子弹碰撞敌方坦克算法
    def hitEnemyTank(self):
        for eTank in MainGame.EnemyTank_list:
            # 判断我方子弹是否与敌方坦克碰撞
            if pygame.sprite.collide_rect(eTank, self):
                # 产生爆炸效果
                explode = Explode(eTank)
                MainGame.Explode_list.append(explode)
                # 修改两者状态
                self.live = False
                # 判断敌方坦克状态
                if eTank.hp >= 1:
                    eTank.hp -= 1
                    music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\shotOnTank.mp3')
                    music.play()
                else:
                    eTank.live = False
                    music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\tankExplode_normal.mp3')
                    music.play()
            else:
                pass

    # 敌方子弹碰撞我方坦克算法
    def hitMyTank(self):
        if pygame.sprite.collide_rect(self, MainGame.TANK_P1):
            # 修改子弹状态
            self.live = False
            # 判断我方坦克生命值
            if MainGame.TANK_P1.hp - 1 == 0:
                # 修改坦克生命值
                MainGame.TANK_P1.hp = 0
                # 修改我方坦克状态
                MainGame.TANK_P1.live = False
                # 增加爆炸效果
                explode = Explode(MainGame.TANK_P1)
                MainGame.Explode_list.append(explode)
                # 启用爆炸音效
                music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\tankExplode_normal.mp3')
                music.play()
                # 累计失败次数
                MyTank.recover_time += 1
            else:
                # 修改坦克生命值
                MainGame.TANK_P1.hp -= 1
                # 启用击中效果

                # 启用击中音效
                music = Music(r"tank_music\shotOnTank.mp3")
                music.play()

    # 子弹与墙壁碰撞方法
    def hitBarrier(self):
        for barrier in MainGame.Barrier_list:
            if pygame.sprite.collide_rect(barrier, self) and barrier.hp != -1:
                # 修改子弹状态
                self.live = False
                # 判断墙壁生命值是否足够
                if barrier.hp >= 1:
                    # 扣除墙壁生命值
                    barrier.hp -= 1
                else:
                    # 墙壁生命值不足，使墙壁失效
                    barrier.live = False

    # 子弹与我方核心建筑碰撞
    def hitHeart(self):
        if pygame.sprite.collide_rect(MainGame.heart, self):
            # 子弹碰撞后失效
            self.live = False
            if MainGame.heart.hp >= 1:
                # 扣除核心建筑生命值
                MainGame.heart.hp -= 1
                music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\shotOnTank.mp3')
                music.play()
            else:
                # 使核心建筑失效
                MainGame.heart.live = False
                music = Music(r'E:\summer_term_2023\pythonProject\tankGame\tank_music\tankExplode_normal.mp3')
                music.play()


# 爆炸类
class Explode(object):
    def __init__(self, tank):
        self.rect = tank.rect
        self.step = 0
        self.images = [
            pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\explode1.png'),
            pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\explode2.png'),
            pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\explode3.png'),
            pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\explode4.png')
        ]
        self.image = self.images[self.step]
        self.live = True

    # 展示爆炸效果
    def displayExplode(self):
        if self.step < len(self.images):
            MainGame.window.blit(self.image, self.rect)
            self.image = self.images[self.step]
            self.step += 1
        else:
            self.live = False
            self.step = 0


# 障碍物类类 石墙
class Wall_stone(BaseItem):
    def __init__(self, left, top):
        super().__init__()
        self.image = pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\wall_stone.png')
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        # 用以判断墙壁是否应该在窗口中展示
        self.live = True
        # 用以记录墙壁的生命值
        self.hp = 100

    # 展示墙壁
    def displayBarrier(self):
        MainGame.window.blit(self.image, self.rect)


# 障碍物类  木墙
class Wall_wood(BaseItem):
    def __init__(self, left, top):
        super().__init__()
        self.image = pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\wall_wood.png')
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        # 用以判断墙壁是否应该在窗口中展示
        self.live = True
        # 用以记录墙壁的生命值
        self.hp = 2

    # 展示墙壁
    def displayBarrier(self):
        MainGame.window.blit(self.image, self.rect)


# 障碍物类 河流
class River(BaseItem):
    def __init__(self, left, top):
        super().__init__()
        self.image = pygame.image.load(r"E:\summer_term_2023\pythonProject\tankGame\tank_image\river.png")
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        # 河流类障碍物理应没有生命值判断，但为了后期添加功能玩法，保留此属性
        self.live = True
        self.hp = -1

    # 展示该类障碍物的方法
    def displayBarrier(self):
        MainGame.window.blit(self.image, self.rect)


# 核心建筑类
class Heart(BaseItem):
    def __init__(self, left, top):
        super().__init__()
        self.image = pygame.image.load(r'E:\summer_term_2023\pythonProject\tankGame\tank_image\my_heart.png')
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top
        self.live = True
        # 为核心物体添加生命值
        self.hp = 3

    def display(self):
        MainGame.window.blit(self.image, self.rect)


# 音效类
class Music(object):
    def __init__(self, fileName):
        self.fileName = fileName
        # 先初始化混响器
        pygame.mixer.init()
        pygame.mixer.music.load(self.fileName)

    # 开始播放音乐
    def play(self):
        pygame.mixer.music.play(loops=0)


class Map(object):
    def __init__(self):
        pass

# 启动游戏类
MainGame().startGame()
